/**
 * 
 */
package boundary;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

import calculator.DialogBuilder;
import calculator.FileUtils;
import calculator.MenuBuilder;
import executor.QuadTree;

import boundary.components.CascadingWindowPositioner;
import boundary.components.ImageFileChooser;
import boundary.components.JWindowsMenu;
import boundary.components.MyJLabel;
import boundary.components.QuadTreeFileChooser;

/**
 * @author davide
 *
 */
public class MainWindow extends JFrame
{
    private static final long serialVersionUID = 1482435832144400066L;
    
    private JDesktopPane desktop;
    private static JMenuBar menuUpperBar;
    private static Map<String, Integer> windowsNameMapper;

    /**
     * 
     */
    public MainWindow()
    {
	super("Squeeze!");
	this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
	MainWindow.windowsNameMapper = new HashMap<String, Integer>();
	
	this.setIconImage(
		new ImageIcon(FileUtils.getResource("squeeze.gif")).getImage()
	);
	
	this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(@SuppressWarnings("unused") WindowEvent e)
            {
        	MainWindow.this.exitApplication();
            }
	});
	
	this.initializeDesktop();
	this.setLayout(new BorderLayout());
	
	this.add(this.menuBar(), BorderLayout.NORTH);
	this.add(this.desktop, BorderLayout.CENTER);
	
	this.setBounds(10, 10, 800, 640);
	this.setVisible(true);
    }
    
    private void initializeDesktop()
    {
	this.desktop = new JDesktopPane();
	
	this.desktop.addContainerListener(new ContainerListener() {	    
	    private boolean hasAtLeastOneFrame(JDesktopPane desk)
	    {
		return desk.getAllFrames().length > 0;
	    }
	    
	    private void setMenuVisibility(MainWindow frame, boolean enable, String... menuNames)
	    {
		JMenuBar mbar = frame.getMenuUpperBar();
		
		for(int i = 0; i < mbar.getComponentCount(); ++i)
		{
		    JMenuItem item = (JMenuItem)mbar.getComponent(i);
		    
		    for(String menuName : menuNames) {
			if(menuName.equals(item.getText())) {
			    item.setEnabled(enable);
			}
		    }
		}
	    }
	    
	    @Override
	    public void componentRemoved(@SuppressWarnings("unused") ContainerEvent e)
	    {		
		if(this.hasAtLeastOneFrame(MainWindow.this.getDesktop()) == false) {
		    this.setMenuVisibility(MainWindow.this, false,
			    "Visualizza", "Immagine", "Finestre");
		}
	    }
	    
	    @Override
	    public void componentAdded(@SuppressWarnings("unused") ContainerEvent e)
	    {
		this.setMenuVisibility(MainWindow.this, true,
			"Visualizza", "Immagine", "Finestre");
	    }
	});
    }
    
    public JDesktopPane getDesktop()
    {
        return this.desktop;
    }
    
    public JMenuBar getMenuUpperBar()
    {
        return MainWindow.menuUpperBar;
    }
    
    public static void censusWindow(String fname)
    {
	if(MainWindow.windowsNameMapper.containsKey(fname)) {
	    MainWindow.windowsNameMapper.put(fname,
		    new Integer(MainWindow.windowsNameMapper.get(fname).intValue() + 1));
	}
	
	else {
	    MainWindow.windowsNameMapper.put(fname, new Integer(1));
	}
    }
    
    public static int howManyWindowsWithThatFile(String fname)
    {
	if(MainWindow.windowsNameMapper.containsKey(fname)) {
	    return MainWindow.windowsNameMapper.get(fname).intValue();
	}
	
	return -1;
    }

    private JMenu createFileMenu()
    {
	JMenu file = MenuBuilder.createMenuEntry("File", KeyEvent.VK_F);
	final JMenuItem open, close, closeall, closeother, inside, outside, exit;
	
	open = MenuBuilder.createMenuSubEntry("Apri...",
		new ImageIcon(FileUtils.getResource("open.png")),
		KeyEvent.VK_O,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			MainWindow.this.openImage();
		    }
		});
	
	close = MenuBuilder.createMenuSubEntry("Chiudi",
		new ImageIcon(FileUtils.getResource("close.gif")),
		KeyEvent.VK_W,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			MainWindow.this.closeActiveWindow();
		    }
		});
	
	closeall = MenuBuilder.createMenuSubEntry("Chiudi Tutti",
		//new ImageIcon(FileUtils.getResource("")),
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			MainWindow.this.closeAllWindows();
		    }
		});
	
	closeother = MenuBuilder.createMenuSubEntry("Chiudi Altri",
		//new ImageIcon(FileUtils.getResource("")),
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			MainWindow.this.closeAllOtherWindows();
		    }
		});
	
	inside = MenuBuilder.createMenuSubEntry("Importa",
		new ImageIcon(FileUtils.getResource("import.png")),
		KeyEvent.VK_I,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			MainWindow.this.openQuadTreeImage();
		    }
		});
	
	outside = MenuBuilder.createMenuSubEntry("Esporta",
		new ImageIcon(FileUtils.getResource("esporta.png")),
		KeyEvent.VK_S,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).saveQuadTreeImage();
			}
		    }
		});
	
	exit = MenuBuilder.createMenuSubEntry("Esci",
		new ImageIcon(FileUtils.getResource("exit.png")),
		KeyEvent.VK_Q,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			MainWindow.this.exitApplication();
		    }
		});
	
	file.addMenuListener(new MenuListener() {  
	    @Override
	    public void menuSelected(@SuppressWarnings("unused") MenuEvent arg0) {
		JDesktopPane desk = MainWindow.this.getDesktop();
		ChildWindow frame = (ChildWindow)desk.getSelectedFrame();
		
		if(frame == null || frame.compress.isVisible() ||
			frame.container.getInsertingState() != MyJLabel.InsertingState.INSERTING_WAITING) {
		    outside.setEnabled(false);
		}
		
		else {
		    outside.setEnabled(true);
		}
		
		switch(desk.getAllFrames().length) {
			case 0 : {
			    close.setEnabled(false);
			    closeall.setEnabled(false);
			    closeother.setEnabled(false);
			    break;
			}
			
			case 1 : {
			    close.setEnabled(true);
			    closeall.setEnabled(true);
			    closeother.setEnabled(false);
			    break;
			}
			
			default : {
			    close.setEnabled(true);
			    closeall.setEnabled(true);
			    closeother.setEnabled(true);
			    break;
			}
		}
	    }
	    
	    @Override
	    public void menuDeselected(@SuppressWarnings("unused") MenuEvent arg0) {
		// unimplemented
	    }
	    
	    @Override
	    public void menuCanceled(@SuppressWarnings("unused") MenuEvent arg0) {
		// unimplemented
	    }
	});
	
	file.add(open);
	file.addSeparator();
	
	file.add(close);
	file.add(closeall);
	file.add(closeother);
	file.addSeparator();
	
	file.add(inside);
	file.add(outside);
	file.addSeparator();
	
	file.add(exit);
	return file;
    }
    
    private JMenu createViewMenu()
    {
	final JMenuItem zoomin, zoomout, zoomfit,zoomreal;
	JMenu vmenu = MenuBuilder.createMenuEntry("Visualizza", KeyEvent.VK_V);
	
	zoomin = MenuBuilder.createMenuSubEntry("Aumenta zoom",
		new ImageIcon(FileUtils.getResource("zoom_in.png")),
		KeyEvent.VK_PLUS,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).zoomImageIn();
			}
		    }
		});
	
	zoomout = MenuBuilder.createMenuSubEntry("Riduci zoom",
		new ImageIcon(FileUtils.getResource("zoom_out.png")),
		KeyEvent.VK_MINUS,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).zoomImageOut();
			}
		    }
		});
	
	zoomfit = MenuBuilder.createMenuSubEntry("Reimposta zoom",
		new ImageIcon(FileUtils.getResource("zoom_fit.png")),
		KeyEvent.VK_0,
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).zoomImageFit();
			}
		    }
		});
	
	zoomreal = MenuBuilder.createMenuSubEntry("Dimensioni reali",
		new ImageIcon(FileUtils.getResource("zoom.png")),
		"control alt 0",
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).zoomImageOriginal();
			}
		    }
		});
	
	vmenu.addMenuListener(new MenuListener() {
	    @Override
	    public void menuSelected(@SuppressWarnings("unused") MenuEvent e)
	    {
		ChildWindow frame = (ChildWindow)MainWindow.this.getDesktop().getSelectedFrame();
		
		if(frame == null) {
		    return;
		}
		
		switch(frame.getContainer().getZoomFactor())
		{
			case 25: {
			    zoomout.setEnabled(false);
			    zoomin.setEnabled(true);
			    zoomreal.setEnabled(true);
			    break;
			}
			
			case 100: {
			    zoomout.setEnabled(true);
			    zoomin.setEnabled(true);
			    zoomreal.setEnabled(false);
			    break;
			}
			
			case 200: {
			    zoomout.setEnabled(true);
			    zoomin.setEnabled(false);
			    zoomreal.setEnabled(true);
			    break;
			}
			
			default : {
			    zoomout.setEnabled(true);
			    zoomin.setEnabled(true);
			    zoomreal.setEnabled(true);
			    break;
			}
		}
	    }
	    
	    @Override
	    public void menuDeselected(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	    
	    @Override
	    public void menuCanceled(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	});
	
	vmenu.add(zoomin);
	vmenu.add(zoomout);
	vmenu.add(zoomfit);
	vmenu.add(zoomreal);
	
	vmenu.setEnabled(false);
	return vmenu;
    }
    
    private void addActiveImageMenu(JMenu father)
    {
	final JMenuItem draw, erase, maximizeTop, maximizeBottom, maximizeCenter;
	
	draw = MenuBuilder.createMenuSubEntry("Seleziona area",
		new ImageIcon(FileUtils.getResource("active.png")),
		"control alt A",
		new ActionListener() {
                    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).drawActiveImage();
			}
		    }
		});
	
	erase = MenuBuilder.createMenuSubEntry("Cancella area",
		new ImageIcon(FileUtils.getResource("eraser.png")),
		"control alt Z",
		new ActionListener() {
                    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).eraseActiveImage();
			}
		    }
		});
	
	maximizeTop = MenuBuilder.createMenuSubEntry("Massima superiore",
		"control alt S",
		new ActionListener() {
                    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).maximizedTopActiveImage();
			}
		    }
		});
	
	maximizeBottom = MenuBuilder.createMenuSubEntry("Massima inferiore",
		"control alt I",
		new ActionListener() {
                    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).maximizedBottomActiveImage();
			}
		    }
		});
	
	maximizeCenter = MenuBuilder.createMenuSubEntry("Massima centrale",
		"control alt C",
		new ActionListener() {
                    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).maximizedCenterActiveImage();
			}
		    }
		});
	
	father.add(draw);
	father.add(maximizeTop);
	father.add(maximizeCenter);
	father.add(maximizeBottom);
	father.add(erase);
	
	father.addMenuListener(new MenuListener() {
	    @Override
	    public void menuSelected(@SuppressWarnings("unused") MenuEvent e)
	    {
		JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
		
		if(frame == null) {
		    return;
		}
		
		switch(((ChildWindow)frame).getContainer().getInsertingState())
		{
			case INSERTING_NOTHING : {
			    draw.setEnabled(true);
			    maximizeTop.setEnabled(true);
			    maximizeBottom.setEnabled(true);
			    maximizeCenter.setEnabled(true);
			    erase.setEnabled(false);
			    break;
			}
			
			case INSERTING_WAITING :
			{
			    draw.setEnabled(false);
			    maximizeTop.setEnabled(false);
			    maximizeBottom.setEnabled(false);
			    maximizeCenter.setEnabled(false);
			    
			    if(((ChildWindow)frame).getCompress().isVisible() ||
				    ((ChildWindow)frame).getCompress().isThisImageAlreadyCompressed) {
				erase.setEnabled(false);
			    }
			    
			    else {
				erase.setEnabled(true);
			    }
			    
			    break;
			}
				
			default : {
			    draw.setEnabled(false);
			    maximizeTop.setEnabled(false);
			    maximizeBottom.setEnabled(false);
			    maximizeCenter.setEnabled(false);
			    erase.setEnabled(false);
			    break;
			}
		}
	    }
	    
	    @Override
	    public void menuDeselected(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	    
	    @Override
	    public void menuCanceled(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	});
    }
    
    private void addPolygonMenu(JMenu father)
    {
	final JMenuItem create, erase;
	
	create = MenuBuilder.createMenuSubEntry("Crea poligono",
		new ImageIcon(FileUtils.getResource("polygon.gif")),
		KeyEvent.VK_P,
		new ActionListener() {
                    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
                	JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).drawPolygon();
			}
		    }
		});
	
	erase = MenuBuilder.createMenuSubEntry("Cancella poligono",
		new ImageIcon(FileUtils.getResource("eraser.png")),
		KeyEvent.VK_Z,
		new ActionListener() {
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
			
			if(frame != null) {
			    ((ChildWindow)frame).erasePolygon();
			}
		    }
		});
	
	father.add(create);
	father.add(erase);
	
	father.addMenuListener(new MenuListener() {
	    @Override
	    public void menuSelected(@SuppressWarnings("unused") MenuEvent e)
	    {
		JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
		
		if(frame == null) {
		    return;
		}
		
		switch(((ChildWindow)frame).getContainer().getInsertingState())
		{
			case INSERTING_WAITING :
			{
			    if(((ChildWindow)frame).getContainer().getPolygon().npoints == 0) {
				create.setEnabled(true);
				erase.setEnabled(false);
			    }
			    
			    else {
				create.setEnabled(false);
				erase.setEnabled(true);
			    }
			    
			    break;
			}
				
			default : {
			    erase.setEnabled(false);
			    create.setEnabled(false);
			    break;
			}
		}
	    }
	    
	    @Override
	    public void menuDeselected(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	    
	    @Override
	    public void menuCanceled(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	});
    }
    
    private void addCompressMenu(JMenu father)
    {
	final JMenuItem compress;
	
	compress= MenuBuilder.createMenuSubEntry("Comprimi",
		new ImageIcon(FileUtils.getResource("compress.gif")),
		KeyEvent.VK_ENTER,
		new ActionListener() {
	    		@Override
			public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
			{
	    		    JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
	    		    
	    		    if(frame != null) {
	    			((ChildWindow)frame).createQuadTreeImageWindow();
	    		    }
			}
	});
	
	father.add(compress);
	
	father.addMenuListener(new MenuListener() {
	    @Override
	    public void menuSelected(@SuppressWarnings("unused") MenuEvent e)
	    {
		ChildWindow frame = (ChildWindow)MainWindow.this.getDesktop().getSelectedFrame();
		
		if(frame == null) {
		    return;
		}
		
		if(frame.getContainer().getQuadTree() == null || frame.getCompress().isVisible()) {
		    compress.setEnabled(false);
		}
		
		else {
		    compress.setEnabled(true);
		}
	    }
	    
	    @Override
	    public void menuDeselected(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	    
	    @Override
	    public void menuCanceled(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	});
    }
    
    private void addDiagnosticMenu(JMenu father)
    {
	final JMenuItem subdivision, error;
	
	subdivision = MenuBuilder.createMenuSubEntry("Visiona QuadTree",
		new ImageIcon(FileUtils.getResource("quad-tree.gif")),
		new ActionListener() {
	    		@Override
			public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
			{
	    		    JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
	    		    
	    		    if(frame != null) {
	    			((ChildWindow)frame).createQuadTreeSubdivisionImageWindow();
	    		    }
			}
	});
	
	error = MenuBuilder.createMenuSubEntry("Visiona errori",
		new ActionListener() {
	    		@Override
			public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
			{
	    		    JInternalFrame frame = MainWindow.this.getDesktop().getSelectedFrame();
	    		    
	    		    if(frame != null) {
	    			((ChildWindow)frame).createQuadTreeErrorImageWindow();
	    		    }
			}
	});
	
	father.add(subdivision);
	father.add(error);
	
	father.addMenuListener(new MenuListener() {
	    @Override
	    public void menuSelected(@SuppressWarnings("unused") MenuEvent e)
	    {
		ChildWindow frame = (ChildWindow)MainWindow.this.getDesktop().getSelectedFrame();
		
		if(frame == null) {
		    return;
		}
		
		if(frame.getContainer().getQuadTree() == null) {
		    subdivision.setEnabled(false);
		    error.setEnabled(false);
		}
		
		else {
		    subdivision.setEnabled(true);
		    error.setEnabled(true);
		}
	    }
	    
	    @Override
	    public void menuDeselected(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	    
	    @Override
	    public void menuCanceled(@SuppressWarnings("unused") MenuEvent e) {
		// unimplemented
	    }
	});
    }
    
    private JMenu createImageMenu()
    {
	JMenu image = MenuBuilder.createMenuEntry("Immagine", KeyEvent.VK_I);
	
	this.addActiveImageMenu(image);
	image.addSeparator();
	
	this.addPolygonMenu(image);
	image.addSeparator();
	
	this.addCompressMenu(image);
	image.addSeparator();
	
	this.addDiagnosticMenu(image);
	image.setEnabled(false);
	return image;
    }
    
    private JWindowsMenu createWindowsMenu()
    {
	JWindowsMenu windowsMenu = new JWindowsMenu(this.desktop);
	windowsMenu.setWindowPositioner(new CascadingWindowPositioner(this.desktop));
	
	windowsMenu.setEnabled(false);
	return windowsMenu;
    }
    
    private JMenu createHelpMenu()
    {
	JMenu hmenu = MenuBuilder.createMenuEntry("Aiuto", KeyEvent.VK_A);
	
	hmenu.add(MenuBuilder.createMenuSubEntry("Informazioni",
		new ActionListener()
		{    
		    @Override
		    public void actionPerformed(@SuppressWarnings("unused") ActionEvent e)
		    {
			DialogBuilder.createMessageDialog(MainWindow.this,
				"Squeeze! v1.0.0 creato da Davide Scola nell'ambito del corso\n" +
				"di Interfacce Utente a.a. 2009/2010 :-P",
				"Informazioni su Squeeze!");
		    }
		}));
	
	hmenu.setEnabled(true);
	return hmenu;
    }
    
    private JMenuBar menuBar()
    {
	MainWindow.menuUpperBar = new JMenuBar();

	MainWindow.menuUpperBar.add(this.createFileMenu());
	MainWindow.menuUpperBar.add(this.createViewMenu());
	MainWindow.menuUpperBar.add(this.createImageMenu());
	MainWindow.menuUpperBar.add(this.createWindowsMenu());
	MainWindow.menuUpperBar.add(this.createHelpMenu());
	
	return MainWindow.menuUpperBar;
    }
    
    private void disposeInternalFrame(JInternalFrame frame)
    {
	if(frame != null) {
	    try {
		frame.setClosed(true);
	    }
	    
	    catch(PropertyVetoException ex) {
		// do nothing on error
	    }
	}
    }
    
    public void closeActiveWindow()
    {
	this.disposeInternalFrame(this.getDesktop().getSelectedFrame());
	MainWindow.menuShortcutsBugWorkaround();
    }
    
    public static void closeActiveWindow(JInternalFrame frame)
    {
	if(frame != null) {
	    try {
		frame.setClosed(true);
	    }
	    
	    catch(PropertyVetoException ex) {
		// do nothing on error
	    }
	}
	
	MainWindow.menuShortcutsBugWorkaround();
    }
    
    protected void closeAllWindows()
    {
	for(JInternalFrame frame: this.getDesktop().getAllFrames()) {
	    this.disposeInternalFrame(frame);
	}
	
	MainWindow.menuShortcutsBugWorkaround();
    }
    
    protected void closeAllOtherWindows()
    {
	JInternalFrame active = this.getDesktop().getSelectedFrame();
	
	for(JInternalFrame frame: this.getDesktop().getAllFrames()) {
	    if(frame != active) {
		this.disposeInternalFrame(frame);
	    }
	}
	
	MainWindow.menuShortcutsBugWorkaround();
    }
    
    protected void openImage()
    {
	ImageFileChooser iChooser = new ImageFileChooser();
	
	if (iChooser.isValidSelection(this) == true) {
	    this.launchChildWindowIfNecessary(iChooser.getSelectedFile());
	}
	
	MainWindow.menuShortcutsBugWorkaround();
    }
    
    protected void launchChildWindowIfNecessary(File f)
    {
        if(f == null || f.canRead() == false || f.isFile() == false) {
            DialogBuilder.createErrorDialog(this,
		    "Impossibile accedere al file specificato", "File invalido");
        }
        
        else {
            try {
        	new ChildWindow(f, this.desktop);
            }
            
            catch(IllegalArgumentException ex) {
        	DialogBuilder.createErrorDialog(this,
    		    ex.getMessage(), "Immagine invalida");
            }
        }
    }
    
    protected void openQuadTreeImage()
    {
	QuadTreeFileChooser qChooser = new QuadTreeFileChooser();
	
	if (qChooser.isValidSelection(this) == true) {
	    this.launchQuadTreeWindowIfNecessary(qChooser.getSelectedFile());
	}
	
	MainWindow.menuShortcutsBugWorkaround();
    }
    
    protected void launchQuadTreeWindowIfNecessary(File f)
    {
	try {
	    QuadTree qTree =  QuadTree.read(new FileInputStream(f));
	    
	    new ChildWindow(f, qTree, this.desktop);
	}
	
	catch(IOException ex) {
	    DialogBuilder.createErrorDialog(this,
		    "Impossibile accedere al file specificato", "File invalido");
	}
	
	catch(IllegalArgumentException ex) {
	    DialogBuilder.createErrorDialog(this,
		    ex.getMessage(), "QuadTree invalido");
        }
    }
    
    protected void exitApplication()
    {
	int n = DialogBuilder.createConfirmDialog(this,
			"Sei veramente sicuro di voler uscire?",
			"Conferma Uscita");
	
	if(n == JOptionPane.YES_OPTION) {
	    MainWindow.this.closeAllWindows();
	    System.exit(0);
	}
    }
    
    public static void menuShortcutsBugWorkaround()
    {
	for(int i = 0; i < MainWindow.menuUpperBar.getComponentCount(); ++i)
	{
	    JMenuItem item = (JMenuItem)MainWindow.menuUpperBar.getComponent(i);
	    
	    item.setSelected(true);
	    item.setSelected(false);
	}
    }
}
